package com.wandian.texas.net;

import com.wandian.command.CommandSet;
import com.wandian.util.Log;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @date : 2012-9-25, 16:59:35
 * @author: long
 * @email :108232706
 * @qq.com
 * @description: SessionManager类
 */
public class SessionManager implements ISessionManager {

    private ServerSocket serverSocket = null;
    private static SessionManager instance = null;
//    private Map<Integer, SessionObject> sessions = null;
    private ArrayList<SessionObject> sessions = null;
    private boolean started = false;
    private int maxThread;
    private int currentCount;

    public synchronized static SessionManager getInstance() throws IOException {
        if (instance == null) {
            instance = new SessionManager();
        }
        return instance;
    }

    private boolean initCommand() {
        return initComponent(CommandSet.load(), "命令加载");
    }

    public boolean initComponent(boolean initResult, String componentName) {
        if (!initResult) {
            Log.error(componentName + "错误");
        } else {
            Log.info(componentName + "加载完成");
        }
        return initResult;
    }

    public boolean start(int port, int maxCount) throws IOException {
        if (!isStarted()) {
            if (!initCommand()) {
                return false;
            }
            serverSocket = new ServerSocket(port);
//            sessions = Collections.synchronizedMap(new HashMap<Integer, SessionObject>());
            sessions = new ArrayList<SessionObject>();
            maxThread = maxCount;
            setStarted(true);
//            new Receiver().run();
            Log.info("服务器启动成功，端口:" + port);
        }
        return true;
    }

    public void acceptProcessor() {
        new acceptProcessorThread().start();
    }

    public boolean stop() {
        if (serverSocket != null) {
            if (!serverSocket.isClosed()) {
                try {
                    serverSocket.close();
                    sessions.clear();
                    currentCount = 0;
                } catch (IOException ex) {
                    Log.info(ex);
                    return false;
                }
            }
            serverSocket = null;
            setStarted(false);
        }
        Log.info("服务器停止成功！:");
        return true;
    }

    /**
     * @return the started
     */
    public boolean isStarted() {
        return started;
    }

    /**
     * @param started the started to set
     */
    public void setStarted(boolean started) {
        this.started = started;
    }

    // 开启一个线程用来接收客户端的连接  
    class acceptProcessorThread extends Thread {

        public acceptProcessorThread() {
            super("acceptProcessorThread");
        }

        @Override
        public void run() {
            while (isStarted()) {
                try {
                    if (sessions.size() >= maxThread) {
                        return;
                    }
                    Socket socket = serverSocket.accept();
                    onAcceptCompleted(socket);
                } catch (SocketException e) {
                } catch (IOException e1) {
                    Log.info(e1);
                }
            }
            Log.info("退出acceptProcessor,停止接受socket");
        }
    }

    /**
     * 当接受一个socket完成
     *
     * @param socket
     * @throws SocketException
     * @throws IOException
     */
    public void onAcceptCompleted(Socket socket) throws SocketException, IOException {
        //                    socket.setTcpNoDelay(true); 
//                    //中断后未传输数据可传输的时间（秒）,defalut false
//                    socket.setSoLinger(true, 240); 
//                    //设置超时时间(毫秒)
//                    socket.setSoTimeout(180000);
//                    //设置接收的缓冲区大小
        socket.setReceiveBufferSize(1024 * 5);//接收缓冲区5k
        socket.setSendBufferSize(1024 * 5);//发送缓冲区5k
        socket.setKeepAlive(true);//启用/禁用SO_KEEPALIVE。    

        currentCount++;
        Log.info("当前线程数：" + currentCount);
        SessionObject sessionObj = new SessionObject();
        sessionObj.setSocket(socket);
        sessionObj.setCount(currentCount);
//        sessionObj.printSocket();
        sessions.add(sessionObj);
        //命令接受线程                
        new CommandReceiver(sessionObj).start();
    }

    // 负责发送时间的线程类  
    class ChatThread implements Runnable {

        private final SessionObject session;
        private DataOutputStream outStream;

        public ChatThread(SessionObject _session) {
            this.session = _session;
            try {
                outStream = new DataOutputStream(session.getSocket().getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @SuppressWarnings("deprecation")
        public void run() {
            while (session.isStarted()) {
                try {
                    String remoteSocketAddress = session.getSocket()
                            .getRemoteSocketAddress().toString();
                    int start = remoteSocketAddress.indexOf("/") + 1;
                    int end = remoteSocketAddress.indexOf(":");
                    Log.info("#CLIENT端为"
                            + remoteSocketAddress.substring(start, end)
                            + ",开始同步时间……");
                    String msg = "#当前时间：" + new Date().toLocaleString();
                    outStream.writeUTF(msg);
                    session.addtCount(1);
                    Thread.sleep(8000);
                } catch (IOException e1) {
                    Log.info(e1);
                } catch (InterruptedException e) {
                    Log.info(e);
                }
            }
        }
    }
    // 负责接受客户端命令的线程类  

    class CommandReceiver extends Thread {

        private final SessionObject client;
        private DataInputStream inputStream;
        private DataOutputStream outStream;
        private Thread thread;
        private boolean flag = true;

        public CommandReceiver(SessionObject client) {
            super("CommandReceiver" + client.getCount());
            this.client = client;
            try {
                inputStream = new DataInputStream(client.getSocket().getInputStream());
                outStream = new DataOutputStream(client.getSocket().getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            client.setStarted(true);
            String remoteSocketAddress1 = client.getSocket()
                    .getRemoteSocketAddress().toString();
            int start = remoteSocketAddress1.indexOf("/") + 1;
            int end = remoteSocketAddress1.indexOf(":");
            Log.info("#CLIENT端为"
                    + remoteSocketAddress1.substring(start, end)
                    + "连接成功……");
            try {
                //        DataOutputStream dos = new DataOutputStream(sessionObj
                //                .getSocket().getOutputStream());
                //        dos.writeUTF();
                client.write(remoteSocketAddress1 + "#连接成功");
            } catch (SocketException ex) {
                Logger.getLogger(SessionManager.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(SessionManager.class.getName()).log(Level.SEVERE, null, ex);
            }
            while (flag) {
                try {
                    try {
//                        client.read();
//                        client.readByData();
                    } catch (Exception ex) {
                        Logger.getLogger(SessionManager.class.getName()).log(Level.SEVERE, null, ex);
                        flag=false;
                        client.setStarted(false);
                    }
                    if (true) {
                        continue;
                    }
                    String command = inputStream.readUTF();
                    if (command.equals("start")) {
                        client.setStarted(true);
                        ChatThread ct = new ChatThread(client);
                        thread = new Thread(ct);
                        thread.start();
                    } else if (command.equals("stop")) {
                        if (thread != null) {
                            client.setStarted(false);
                            Log.info("#CLIENT端为"
                                    + client.getSocket()
                                    .getRemoteSocketAddress().toString()
                                    + "停止发送时间……");
                            outStream.writeUTF("#已发送时间次数为" + client.getCount()
                                    + "次:BYE-BYE!!!!");
                            // 重置发送时间次数  
                            client.setCount(0);
                        } else {
                            outStream.writeUTF("#start命令尚未执行……");
                        }
                    } else {
                        outStream.writeUTF("#命令未完定义，命令为" + command);
                    }
                } catch (SocketException e) {
                    Log.info("#客户端"
                            + client.getSocket()
                            .getRemoteSocketAddress().toString() + "关闭");
                    flag = false;
                    client.setStarted(false);
                    try {
                        client.getSocket().close();
                    } catch (IOException e2) {
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
